/*
 This file is part of Musimage, a project which makes possible listen to music
 and, at the same time, watch pictures related with that music.
 Copyright (C) 2006  David Garcia Narbona 

 Musimage is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 Musimage is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Musimage; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
package client;

import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPANames;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.UnreadableException;
import jade.proto.AchieveREInitiator;

import java.io.IOException;
import java.util.Date;
import java.util.Vector;

import message.MessageStructure;

// Clase que implementa el comportamiento de la aplicaci?n cliente que
// modela la comunicacion con el broker del sistema
public class Comunication extends AchieveREInitiator {

	// ** Atributos **///////////////////////////////////////////
	private MessageStructure ID3;

	private boolean messageReceivedFlag;

	private ACLMessage msg;

	private MainFrame mainframeReference;

	// //////////////////////////////////////////////////////////

	// ** Metodos **//////////////////////////////////////////////

	// Constructor
	public Comunication(Agent _agent, MainFrame _mainframeReference,
			MessageStructure _ID3) {

		super(_agent, null);

		messageReceivedFlag = true;

		mainframeReference = _mainframeReference;
		ID3 = _ID3;
	}

	// Metodo que envia el mensaje REQUEST que inicia la conversacion
	protected Vector prepareRequests(ACLMessage request) {

		ACLMessage message = new ACLMessage(ACLMessage.REQUEST);
		AID broker = new AID();

		// Busca que agente es el que proporciona el servicio de
		// enlace de musica y fotos a traves del agente "paginas amarillas"
		DFAgentDescription DFTemplate = new DFAgentDescription();
		ServiceDescription serviceDescription = new ServiceDescription();

		serviceDescription.setType("music-image-linking");
		DFTemplate.addServices(serviceDescription);

		Vector v = new Vector(1);

		try {
			DFAgentDescription[] server = DFService.search(myAgent, DFTemplate);
			broker = server[0].getName();

			// /////////////////////////////////////////////////////

			message.addReceiver(broker);
			message.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);

			// We want to receive a reply in 3 secs
			message.setReplyByDate(new Date(System.currentTimeMillis() + 3000));

			message.setContentObject(ID3);

			v.addElement(message);
		} catch (FIPAException fe) {
			fe.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return v;
	}

	protected void handleAgree(ACLMessage agree) {

		if (agree.getPerformative() == ACLMessage.AGREE) {

			System.out.println("Agent " + agree.getSender().getName()
					+ " sends AGREE ACLMessage");
		} else {

			System.out.println("Agent " + agree.getSender().getName()
					+ " sends IFNFORM ACLMessage when expected AGREE");

			handleInform(agree);
			// eliminar comportamiento
		}
	}

	protected void handleInform(ACLMessage inform) {

		MessageStructure URLs = new MessageStructure();

		// Realizar la descarga de las imagenes del servidor de imagenes
		// a traves de las URL's recibidas del broker
		// System.out.println("Agente "+inform.getSender().getName()+" manda
		// respuesta con: " + inform.getContent());
		messageReceivedFlag = false;

		try {

			URLs = (MessageStructure) inform.getContentObject();
		} catch (UnreadableException e3) {

			System.err
					.println("ERROR in ProcessClientRequest class on processRequest() method: "
							+ e3.getMessage());
		} catch (ClassCastException e) {

			System.err
					.println("ERROR in ProcessClientRequest class on processRequest() method: "
							+ e.getMessage());
		}

		// referencia Mainframe pasandole URLs
		mainframeReference.imageList(URLs);

	}

	protected void handleRefuse(ACLMessage refuse) {

		// Tratar problema en el que el broker no puede solventar peticion
		System.out.println("Agent " + refuse.getSender().getName()
				+ " refused to perform the requested action");
		messageReceivedFlag = false;
	}

	protected void handleFailure(ACLMessage failure) {

		if (failure.getSender().equals(myAgent.getAMS())) {
			// FAILURE notification from the JADE runtime: the receiver
			// does not exist
			System.out.println("Responder does not exist");
		} else {
			// Tratar problema en el que el broker no puede realizar la
			// interseccion
			System.out.println("Agent " + failure.getSender().getName()
					+ " failed to perform the requested action");
		}
		messageReceivedFlag = false;
	}

	protected void handleAllResultNotifications(Vector notifications) {

		// El broker no responde mediante ning?n mensaje a la peticion
		// de AGREE en el tiempo establecido
		if (messageReceivedFlag) {
			System.out.println("El broker no responde.");
		}
	}

	// Si tarda demasiado en llegar el mensaje AGREE
	protected void handleAllResponses(Vector responses) {

		if (responses.size() == 0)
			reset();

	}

	// //////////////////////////////////////////////////////////
}
